package com.sheng.project.demo.utils;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.IdUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * description RSACryptor
 * author wy
 * date 2020-03-30 14:40
 **/

public class RSACryptor {
    public static final String KEY_ALGORITHM = "RSA";
    private static Map<Integer, String> keyMap = new HashMap<Integer, String>();  //用于封装随机产生的公钥与私钥

//    public static void main(String[] args) throws Exception {
//        //生成公钥和私钥
//        Map<String, String> map = genKeyPair();
////        String privateKey = "MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEAiGtHyllb1YCJjmIpOkg82ZCSfu76pS1PhiTGaUEG2Z3xLkgyrLZpPQQNlbEUsQ32r2AcjEP81/UO/EOdBr91JwIDAQABAkAMJEhCeUuUKBmWI6R5vH41+wke5RRH6U1/qfxC1/fNHIFSMaXK05ptJusMGSY6oEiHFYt7sx2QbdHdEP7YzsX5AiEAw/K/tXlb4pOZTa3n6QNCj13MRTRjEgt2L9Bnk3peqP0CIQCyOiFO9ypemkKrwo9bAA/+f1mIYKyAyOx94EpJzzFR8wIhALB0RLFedSFHu3EZX1MVTXYfiJj1gRW53pdWPD+xndbdAiEAip7V21I4nR4ELw2DbHbu+bXZUE5IvV4JOpphjWjeZmsCIQCpVYlfBmVO55yiD9xB7t75jnjL+Ks0CWgjTgVfe65ojg==";
////        String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIhrR8pZW9WAiY5iKTpIPNmQkn7u+qUtT4YkxmlBBtmd8S5IMqy2aT0EDZWxFLEN9q9gHIxD/Nf1DvxDnQa/dScCAwEAAQ==";
//        //加密字符串
//        String message = "{\"cardNoDecimal\":\"4232840624\",\"companyId\":\"1166313216997851136\",\"deviceId\":\"1243204048417456128\",\"industryCode\":\"62\",\"memberId\":\"1212075212703531008\",\"onLine\":false,\"operatorId\":\"1212075212703531008\",\"recognitionTime\":\"2024-05-27 14:48:35\",\"scenario\":2,\"terminalId\":\"1243204112145711104\",\"totalPrice\":1.0,\"uploadId\":\"f94dd6ee1829490080c42a02011c96e2\"}";
//        System.out.println("随机生成的公钥为:" + keyMap.get(0));
//        System.out.println("随机生成的私钥为:" + keyMap.get(1));
////        String messageEn = encrypt(message, keyMap.get(0));
//        String messageEn = encryptByPublicKey(keyMap.get(0), message.getBytes());
//        System.out.println(message + "\t加密后的字符串为:" + messageEn);
//

    /// /        String messageDe = decrypt(messageEn, keyMap.get(1));
//        String messageDe = decryptByPublicKey(messageEn, keyMap.get(1));
//        System.out.println("还原后的字符串为:" + messageDe);
//    }
    public static void main(String[] args) throws Exception {
        // 罗湖小学
//        String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANS06kfnkfiTefWH3AnsSmENeEyUcL30jkdCbZ0d52wx2GYphol32fCiKRtXuAoW2GJX6uIEyrBsAYkD3QawHvsCAwEAAQ==";
        // liya测试
        String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJydrqUuBSNapfw0758iYnuglrRkzUCI5ubSVfy1CLv93iITd1eIgB5cYanZkQQ75GBepE5dRmR/2z/t/E7h3CMCAwEAAQ==";
        String secretKey = CharacterUtils.getRandomString(16);
//        String message = "{\"cardNoDecimal\":\"4232840624\",\"companyId\":\"1166313216997851136\",\"deviceId\":\"1243204048417456128\",\"industryCode\":\"62\",\"memberId\":\"1245040874371416064\",\"onLine\":false,\"operatorId\":\"1212075212703531008\",\"recognitionTime\":\"2024-05-28 16:04:35\",\"scenario\":2,\"terminalId\":\"1243204112145711104\",\"totalPrice\":3.4,\"uploadId\":\"f94dd6ee1829490080c42a02034c96e2\"}";
        String message = "{\"xxx1\":\"xxx1\",\"xxx2\":\"xxx2\",\"xxx3\":\"xxx3\"}";
        System.out.println("password：" + encrypt(secretKey, publicKey));
        System.out.println("cipherText：" + AesUtils.encrypt(message, secretKey));

        String yhDate, calledAnswerTime;
        yhDate = "";
        yhDate = "2024-06-14";
        calledAnswerTime = "2024-06-17";
        int compare = StringUtils.compare(StringUtils.isNotBlank(yhDate) && yhDate.length() >= 10 ? yhDate.substring(0, 10) : calledAnswerTime, StringUtils.isNotBlank(calledAnswerTime) && calledAnswerTime.length() >= 10 ? calledAnswerTime.substring(0, 10) : calledAnswerTime);
        System.out.println("compare: " + compare);
        String format = LocalDateTimeUtil.now().plusSeconds(60).format(new DateTimeFormatterBuilder()
                .parseCaseInsensitive()
                .append(DateTimeFormatter.ISO_LOCAL_DATE)
                .appendLiteral(' ')
                .append(DateTimeFormatter.ISO_LOCAL_TIME)
                .toFormatter());
        System.out.println(format);
        System.out.println(DateUtil.now());
        System.out.println(DateUtil.now().substring(0, 7));
        System.out.println(LocalDate.parse("2024-08-01").minusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        System.out.println(LocalDate.parse("2024-08-01").plusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        System.out.println(LocalDateTimeUtil.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        System.out.println(StringUtils.compare("2024-07-05", "2024-07-05 16:04:35"));
        System.out.println(StringUtils.compare(null, "2024-07-05 16:04:35"));
        System.out.println(DateUtil.dayOfWeek(new SimpleDateFormat("yyyy-MM-dd").parse("2024-09-09")));
        System.out.println(DateUtil.today());
        System.out.println(DateUtil.format(new DateTime(), "yyyyMMdd"));
        System.out.println(Convert.digitToChinese(123456));
        System.out.println(IdUtil.getSnowflake().nextIdStr());
        System.out.println(IdUtil.fastSimpleUUID());
        System.out.println(IdUtil.getSnowflake().nextIdStr());
    }

    /**
     * 随机生成密钥对
     *
     * @throws NoSuchAlgorithmException
     */
    public static Map genKeyPair() throws NoSuchAlgorithmException {
        // KeyPairGenerator类用于生成公钥和私钥对，基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        // 初始化密钥对生成器，密钥大小为96-1024位
        keyPairGen.initialize(1024, new SecureRandom());
        // 生成一个密钥对，保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥
        String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
        // 得到私钥字符串
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
        // 将公钥和私钥保存到Map
        keyMap.put(0, publicKeyString);  //0表示公钥
        keyMap.put(1, privateKeyString);  //1表示私钥
        return keyMap;
    }

    /**
     * RSA公钥加密
     *
     * @param str       加密字符串
     * @param publicKey 公钥
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     */
    public static String encrypt(String str, String publicKey) throws Exception {
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
        //RSA加密
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
        return outStr;
    }

    /**
     * RSA私钥解密
     *
     * @param str        加密字符串
     * @param privateKey 私钥
     * @return 铭文
     * @throws Exception 解密过程中的异常信息
     */
    public static String decrypt(String str, String privateKey) throws Exception {
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
        //base64编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
        //RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        String outStr = new String(cipher.doFinal(inputByte));
        return outStr;
    }

    /**
     * 公钥解密过程
     *
     * @param cipherText 密文
     * @param publicKey  公钥
     * @return 明文
     * @throws Exception 解密过程中的异常信息
     */
    public static String decryptByPublicKey(String cipherText, String publicKey) throws Exception {
        byte[] keyBytes = Base64.decodeBase64(publicKey.replace("\r|\n", ""));
        Key key = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyBytes));
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] cipherTextData = Base64.decodeBase64(cipherText.getBytes("UTF-8"));
        byte[] plainTextData = cipher.doFinal(cipherTextData);
        return new String(plainTextData);
    }

    /**
     * 公钥加密
     *
     * @param publicKey
     * @param plainTextData
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKey(String publicKey, byte[] plainTextData) throws Exception {
        if (publicKey == null) {
            throw new Exception("加密公钥为空, 请设置");
        }
        try {
            //对公钥解密
            byte[] keyBytes = decryptBASE64(publicKey);
            //取公钥
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            Key key = keyFactory.generatePublic(x509EncodedKeySpec);
            // 使用默认RSA
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] output = null;
            if (plainTextData.length <= 245) {
                output = cipher.doFinal(plainTextData);
            } else {
                for (int i = 0; i < plainTextData.length; i += 245) {
                    byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(plainTextData, i, i + 245));
                    output = ArrayUtils.addAll(output, doFinal);
                }//org.postgresql.util.PSQLException:Bad value for type long:999999999999999999999
                // org.springframework.cloud.configuration.CompatibilityNotMetException:null
                // org.postgresql.jdbc.PgConnection@4682c70e marked as broken because of SQLSTATE(08006),ErrorCode(0)
                // Access denied for 'password'.Authentication that can continue; publickey,gssapi-keyex,gssapi-with-mic,password(11)
            }
//            byte[] output = cipher.doFinal(plainTextData);
            return encryptBASE64(output);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此加密算法");
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        } catch (InvalidKeyException e) {
            throw new Exception("加密公钥非法,请检查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("明文长度非法");
        } catch (BadPaddingException e) {
            throw new Exception("明文数据已损坏");
        }
    }

    //编码返回字符串
    public static String encryptBASE64(byte[] key) throws Exception {
        return Base64.encodeBase64String(key);
    }

    public static byte[] decryptBASE64(String key) throws Exception {
//        return (new BASE64Decoder()).decodeBuffer(key);
        return null;
    }

    @Test
    public void test001() {
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 设置开始日期和结束日期
        String dataDayFrom = "2025-03-28";
        String dataDayTo = "2025-04-04";

        // 解析日期
        LocalDate startDate = LocalDate.parse(dataDayFrom, formatter);
        LocalDate endDate = LocalDate.parse(dataDayTo, formatter);

        // 存放星期几的集合
        Set<String> weekdays = new HashSet<>();

        // 遍历日期范围
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            // 获取当前日期的星期几 (1=周一, 7=周日)
            int dayOfWeek = currentDate.getDayOfWeek().getValue();
            weekdays.add(String.valueOf(dayOfWeek));

            // 移动到下一个日期
            currentDate = currentDate.plusDays(1);
        }

        // 打印结果
        System.out.println(weekdays);
    }

    @Test
    public void test02() throws Exception {
//        String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJydrqUuBSNapfw0758iYnuglrRkzUCI5ubSVfy1CLv93iITd1eIgB5cYanZkQQ75GBepE5dRmR/2z/t/E7h3CMCAwEAAQ==";
        String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtqo0e2FnzDainJ901roEeoUyG7khDVDHdmSvoWTWC04AhH8vQHqKSPMYqzSudJMOVvDYSSo9YGi9xLbCH72aqoP4cFWTZfcHdO0DQ7A4k4WxTfvqxlpiqIDbYk1diKQJtdESeSLiMMAJn0yfajCTsbCRn7jJGFuADQT1fSWZO1LvJe6gsDUeKKKabk8tLSeJYAXbjXjBj0y4gTVCb5qiNmyDghR/1kDatbA66tOFTcht31C0KdRJlhX43Whv5emsNk0aDHqpep6HiqV+dKEqeCtuKE5K+XruxEzv4BHAQKi7Qg85hgbaDWeorw3QSdJC33VHmPeyymJu2cpsldnCfwIDAQAB";
        String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC2qjR7YWfMNqKc\n" +
                "n3TWugR6hTIbuSENUMd2ZK+hZNYLTgCEfy9AeopI8xirNK50kw5W8NhJKj1gaL3E\n" +
                "tsIfvZqqg/hwVZNl9wd07QNDsDiThbFN++rGWmKogNtiTV2IpAm10RJ5IuIwwAmf\n" +
                "TJ9qMJOxsJGfuMkYW4ANBPV9JZk7Uu8l7qCwNR4ooppuTy0tJ4lgBduNeMGPTLiB\n" +
                "NUJvmqI2bIOCFH/WQNq1sDrq04VNyG3fULQp1EmWFfjdaG/l6aw2TRoMeql6noeK\n" +
                "pX50oSp4K24oTkr5eu7ETO/gEcBAqLtCDzmGBtoNZ6ivDdBJ0kLfdUeY97LKYm7Z\n" +
                "ymyV2cJ/AgMBAAECggEAPI4EQ/qwjFR4Z++8rgqQvYU2bVZcDKwA09DhIGHrS2ga\n" +
                "Z9I5+eglu7VLMkaOpvqxQEUrjmXAXxuZ/YKQrDEQ+wIw9ByKdr0D7dE8yc27k7w4\n" +
                "YR/oXsVL+4xsLhRzs36d8XZT53CXB45CIlsmZe+gpsFgJVD+6WI7+xTvxQMX30A4\n" +
                "+jmLjKF+dfBHpOeTglWAOjERDBXlQqLhFaot/ubiHOejALkR7O60E1VkgofE2JAu\n" +
                "dfGJaTUv+BluM7uSZAEA1YhslXAGAhLWBcbm0yoEhW3dkfWsd5JLMoYpFCANopW5\n" +
                "FRNk6xLvVGmX9ghjke3ct9EWhRTFqhHvp0URXWwJYQKBgQDwGGK4DcWK4xM3rjXe\n" +
                "sFbPcoYTQWZr20oJH0H++FY2IS3r1Tpi+jlZiTwjcNUmmsPHB7w+5LbffHEJ2CPT\n" +
                "gFHOAnT6GL91Ji/u3dHPub8zgGmHkAr+2sxbOSCw4TWStXfADrfqcWgVWuBgM6JI\n" +
                "nddhptbVeSVefe7pBiNzz/9kNwKBgQDCw+VYYi6XHqS93fdp2VkY804E/X2dsRYt\n" +
                "eqgFQwi9k9hjBiTDTsoaSHTZANwishxM11gi2Z9MM/mOdL0soJAm5eVYFqY2o15z\n" +
                "z29OjjDwWipbrIPjKixdJKTKw3W2+XceSADGFaKg4md23WeBPAYE22qwvOAVS9HW\n" +
                "jOvlQRZ/+QKBgBjabV2gD1LRLqwU3H6wwku3DynvGysPCBrpoWtDSalQxfAjomec\n" +
                "f1NFYXRJucbFPn7bziC0jDmWKB1cwliib9Vja7h311nJGi0fyRg3ohMyt7nQr1Ky\n" +
                "U3Ud9MRai7EkF8FJxL///UY4ogFTVvktXZ4+Jv7yC2w8nP6CJClY3pcBAoGAMnY2\n" +
                "8dNeZuEVpevgspgRsZk4Waqj5TuAl3/0EIjxtsybf+yTkdbUHkMvoxnJ72NeWbph\n" +
                "p4Xi9AdzXSl56hofvzRJW61imz1wt2jDWgMVQvDZkK797Nl8bRWVbMN/uEyiREI7\n" +
                "kRcB79U5IV7z9lPq608+MVR+aoYedAxHAjr+7WECgYA5fwWh1FiT80NhXUofGBhG\n" +
                "EfmqXq/2ivY2RFQMXQBd3IyGB7xWLFPb5SjqBun1WaUybqukEqScVdoahq6CnS3r\n" +
                "9K4gqzctp/Rk9rg/UfVrCMcwk7OX9gR/AFYeHJO8Frbn4+PTqFcTxpiT5DGpmIN1\n" +
                "MLe18pagP1us5yXThc2Vbg==";
        // 生成一个字符串
        String secretKey = CharacterUtils.getRandomString(16);
        System.out.println("secretKey：" + secretKey);
        String message = "{\"cardNoDecimal\":\"4232840624\",\"companyId\":\"1166313216997851136\",\"deviceId\":\"1243204048417456128\",\"industryCode\":\"62\",\"memberId\":\"1245040874371416064\",\"onLine\":false,\"operatorId\":\"1212075212703531008\",\"recognitionTime\":\"2024-05-28 16:04:35\",\"scenario\":2,\"terminalId\":\"1243204112145711104\",\"totalPrice\":3.4,\"uploadId\":\"f94dd6ee1829490080c42a02034c96e2\"}";
        // 将字符串加密
        String password = encrypt(secretKey, publicKey);
        System.out.println("password：" + password);
        // 再进行加密
        String cipherText = AesUtils.encrypt(message, secretKey);
        System.out.println("cipherText：" + cipherText);


        System.out.println("解密------------------------------------------------");

        // 解密
        RSAUtilV2 rsaUtilV2 = new RSAUtilV2();
        AESUtilV2 aesUtil = new AESUtilV2();
        // RSA解密
        String aesKey = rsaUtilV2.decryptByPrivateKey(password, privateKey);
        System.out.println("aesKey：" + aesKey);
        String plainText = aesUtil.decrypt(cipherText, aesKey);
        System.out.println("plainText：" + plainText);
    }

    @Test
    public void test03() throws Exception {
        String cipherText = "";
        byte[] bytes = Base64.decodeBase64(cipherText);
    }
}
